package com.linkoog.devtools.intellij.ui.table;

import com.intellij.ui.JBColor;
import com.intellij.ui.render.RenderingUtil;
import com.intellij.ui.table.TableView;
import com.intellij.util.SmartList;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.linkoog.devtools.intellij.ui.table.column_info.TableClickable;
import com.linkoog.devtools.intellij.ui.table.column_info.TableClickableProvider;
import lombok.Getter;

import javax.swing.*;
import javax.swing.table.TableCellEditor;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

@Getter
public class ListTableView<T extends TableRowData> extends TableView<T> {

    private final TablePopupMenuProvider<T> popupMenuProvider;
    private final EmptyRowProvider<T> emptyRowProvider;

    public ListTableView(){
        this(null,null);
    }

    public ListTableView(TablePopupMenuProvider<T> popupMenuProvider, EmptyRowProvider<T> emptyRowProvider) {
        this.popupMenuProvider = popupMenuProvider;
        this.emptyRowProvider = emptyRowProvider;
        setRowMargin(1);
        setRowHeight(30);
        //this.setShowGrid(false);
        //this.setCellSelectionEnabled(false);
        this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        this.putClientProperty(RenderingUtil.PAINT_HOVERED_BACKGROUND, false);

        //禁止拖动表头
        getTableHeader().setReorderingAllowed(false);
        setRowSelectionAllowed(false);
        //setBorder(Borders.empty(1));
        setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
        this.putClientProperty(RenderingUtil.PAINT_HOVERED_BACKGROUND, false);
        //this.putClientProperty(RenderingUtil.CUSTOM_SELECTION_BACKGROUND, (Supplier<Color>) () -> JBColor.lightGray);

        setBackground(JBColor.white);
        setSelectionBackground(JBColor.lightGray);

        addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent e) {
                showPopupMenu(e);
                ListTableView.this.mousePressed(e);
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                showPopupMenu(e);
                ListTableView.this.mouseReleased(e);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                handlerCellClicked(e);
                ListTableView.this.mouseClicked(e);
            }
        });

        /*
        this.tableHeader.setBackground((Color)lm.INSTANCE.getBACKGROUND_COLOR());
        this.tableHeader.setBorder(JBUI.Borders.customLine((Color)lm.INSTANCE.getTABLE_HEADER_GRID_COLOR(), 0, 0, 1, 0));
        this.tableHeader.setDefaultRenderer(new mg());
        this.tableHeader.setUI((TableHeaderUI)new mh());
        this.tableHeader.setReorderingAllowed(false);
        this.setDefaultRenderer((Class)ListWithSelection.class, (TableCellRenderer)new mj());
        this.setDefaultRenderer((Class)Enum.class, (TableCellRenderer)new mj());
        this.setDefaultRenderer((Class)Boolean.TYPE, (TableCellRenderer)new mi(0, 1, null));
        this.setDefaultRenderer((Class)ls.class, (TableCellRenderer)new mi(0, 1, null));
        this.setDefaultRenderer((Class)Object.class, (TableCellRenderer)new mk());
        final mc mc = new mc(project, disposable, hk);
        final mb mb = new mb(project, disposable, hk, mc, (JTable)this);
        this.setDefaultRenderer((Class)File.class, (TableCellRenderer)new ml(mc));
        this.setDefaultRenderer((Class)lv.class, (TableCellRenderer)mc);
        this.setDefaultEditor((Class)lv.class, (TableCellEditor)mb);
        this.setDefaultEditor((Class)ListWithSelection.class, (TableCellEditor)new lZ());
        this.setDefaultEditor((Class)Enum.class, (TableCellEditor)new lZ());
        this.setDefaultEditor((Class)Boolean.TYPE, (TableCellEditor)new lY());
        this.setDefaultEditor((Class)ls.class, (TableCellEditor)new lY());
        this.setDefaultEditor((Class)File.class, (TableCellEditor)new ma(mb, project));
        this.registerTabSwitching();*/
    }

    @Override
    public void setModelAndUpdateColumns(final ListTableModel<T> model) {
        //添加空白的最后一行
        createEmptyRow().ifPresent(model::addRow);

        super.setModel(model);
        createDefaultColumnsFromModel();
        updateColumnSizes();
    }

    public void reloadData(List<T> data){
        SmartList<T> list = new SmartList<>();
        if (data != null && !data.isEmpty()){
            list.addAll(data);
        }

        //添加空白的最后一行
        createEmptyRow().ifPresent(list::add);

        getListTableModel().setItems(list);
        getListTableModel().fireTableDataChanged();
    }

    public Optional<T> createEmptyRow(){
        if (emptyRowProvider != null){
            T emptyRow = emptyRowProvider.createEmptyRow();
            return Optional.ofNullable(emptyRow);
        }
        return Optional.empty();
    }




    protected void mousePressed(MouseEvent e){
    }

    protected void mouseReleased(MouseEvent e) {
    }

    protected void mouseClicked(MouseEvent e) {
    }

    /**
     *
     */
    private void handlerCellClicked(MouseEvent e){
        int rowI = rowAtPoint(e.getPoint());// 得到table的行号
        int columnI = columnAtPoint(e.getPoint());// 得到table的列号
        if (rowI > -1 && columnI >-1){
            //System.out.println("单击鼠标 "+( rowI +1 )+"行"+ columnI +"列" + cellValue);
            //System.out.println("getRowCount" + getRowCount());
            ListTableModel<T> listTableModel = getListTableModel();
            T t = listTableModel.getItem(rowI);
            Object cellValue = listTableModel.getValueAt(rowI, columnI);
            ColumnInfo columnInfo = listTableModel.getColumnInfos()[columnI];
            TableCellEditor tableCellEditor = getCellEditor(rowI, columnI);

            //ColumnInfo的点击处理
            handlerValueClickable(columnInfo,columnInfo, t, cellValue, rowI, columnI);
            //cellValue的点击处理
            handlerValueClickable(cellValue,columnInfo, t, cellValue, rowI, columnI);
            //Editor的点击处理
            handlerValueClickable(tableCellEditor,columnInfo, t, cellValue, rowI, columnI);
        }
    }

    private void handlerValueClickable(Object target,ColumnInfo columnInfo, T t, Object cellValue, int rowI, int columnI) {
        if (target instanceof TableClickable tableClickable){
            tableClickable.click(this, columnInfo, t, cellValue, rowI, columnI);
        }else if (target instanceof TableClickableProvider tableClickableProvider){
            TableClickable tableClickable = tableClickableProvider.getTableClickable();
            if (tableClickable != null){
                tableClickable.click(this,columnInfo, t, cellValue, rowI, columnI);
            }
        }
    }

    private void showPopupMenu(MouseEvent e) {
        int rowI = rowAtPoint(e.getPoint());// 得到table的行号
        int columnI = columnAtPoint(e.getPoint());// 得到table的列号
        if (rowI > -1 && columnI >-1){
            //System.out.println("单击鼠标 "+( rowI +1 )+"行"+ columnI +"列" + cellValue);
            //System.out.println("getRowCount" + getRowCount());
            T t = getListTableModel().getItem(rowI);
            Object cellValue = getListTableModel().getValueAt(rowI, columnI);
            if (e.isPopupTrigger() && popupMenuProvider != null) {
                JPopupMenu menu = popupMenuProvider.createPopupMenu(this, t, cellValue, rowI, columnI);
                if (menu != null) {
                    menu.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        }
    }

    @FunctionalInterface
    public interface TablePopupMenuProvider<T extends TableRowData> {
        JPopupMenu createPopupMenu(ListTableView<T> table, T t, Object cell, int row, int column);
    }


    @FunctionalInterface
    public interface EmptyRowProvider<T extends TableRowData>{
        T createEmptyRow();
    }

}
